home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 9 / CDACTUAL9.iso / share / Dos / VARIOS / pascal / MEMORY.SWG / 0001_Routines for DOS-DPMI communication.pas next >
Encoding:
Pascal/Delphi Source File  |  1996-02-21  |  13.4 KB  |  333 lines

  1. {
  2.  XDR> I'm currently developing an application that I would gladly spread in
  3.  XDR> protected mode... But could someone explain to me what can I NOT do in
  4.  XDR> DPMI pascal
  5.  
  6. This is actually explained quite clearly in Ch. 17 of the BP7 Language Guide.
  7.  
  8. The main difference is that memory is no longer yours to do with as you
  9. please; you can only "touch" memory that has been allocated to your program.
  10. This is where the "protected" in "protected mode" stems from.
  11.  
  12. The following is a rather simplified view of things, but it does illustrate
  13. the general priciple:
  14.  
  15. In pmode a pointer such as ptr($B800, 0) does NOT point to memory location
  16. $B800:0000. The segment part (called the "selector" in pmode), $B800,
  17. is treated as an index into a system maintained table, which *does* contain
  18. the actual physical memory location (called the "base"), and the number of
  19. bytes allocated to that base (called the "limit"). This table is unavailable
  20. to your program.
  21. At the start of your program, all entries in this table are marked "not in
  22. use" and therefore illegal.
  23. During program execution, whenever you attempt to read or write Mem[S:O],
  24. the CPU checks (in that table) to see if S is a legal index (i.e., if S is
  25. a valid base), and if so, whether O is within the limit of that base.
  26. If at least one of these checks fail, the memory access is invalid, and you
  27. will be presented with run time error 216 a.k.a. the dreaded General
  28. Protection Failure (GPF) a.k.a. Exception $0D.
  29.  
  30.  XDR> Ag: I can no more acces the screen at an Obsolute $b800:000 but at
  31.  XDR> absolute Segb800:000, why?
  32.  
  33. Btw: ABSOLUTE SegB800:0 won't compile.
  34. Use "mem[SegB800:0]" instead, or use a pointer, like so:
  35.  
  36. VAR VidMemStart: pointer;
  37. BEGIN VidMemStart:=ptr(SegB800, 0) END;
  38.  
  39. and manipulate video memory using VidMemStart^.
  40.  
  41. The reason should now be clear: $B800 is almost certainly *not* a valid
  42. selector. Since no one has asked the DPMI server to associate selector $B800
  43. with a physical memory location, it is illegal.
  44. You *can* use SegB800, as your program startup code asks the DPMI server to
  45. associate SegB800 with video memory.
  46.  
  47. You should not pass pmode pointers to real mode routines nor the other way
  48. around (they are invalid in the "receiving" mode).
  49. It can be done, but you'll need the cooperation of the DPMI server.
  50. Find a DPMI unit (I can't post mine, as it is commercial). Below you'll
  51. find such a unit - I've never used it, so no guarantees.
  52.  
  53. Notes: - if you attempt to write to code segments, or read from invalid
  54.          pointers, a GPF will result.
  55.        - if you attempt to read an invalid stack element, you will receive
  56.          an Exception $0C (Stack Fault), which BP will convert to run time
  57.          error 202.
  58.        - Exception 6 (Invalid Opcode) is not related to memory accesses.
  59.          It means the CPU has received a couple of bytes which it cannot
  60.          interpret as a valid instruction.
  61.        - prior to distribution, be sure to read file DPMIUSER.DOC.
  62.          You can find that file in archive DOC.ZIP on your BP7 distribution
  63.          disks.
  64.  
  65. The above three exceptions are likely the only ones you'll see.
  66.  
  67. Happy programming,
  68.  
  69. Peter. }
  70.  
  71. ===== Start of includefile FDEFINE.DEF =====
  72.  
  73. { Include file FDEFINE.DEF - general include file for the unit systems
  74.                              conditional defines }
  75.  
  76.  (***************************************************************************
  77.  
  78.             RELEASE 1.04 - as contained in the file PRUS100.LZH
  79.                 by Orazio Czerwenka, 2:2450/540.55, GERMANY
  80.  
  81.                --------------------------------------------
  82.                 organized for Fido's PASCAL related echoes
  83.                --------------------------------------------
  84.  
  85.      06/21/1994 to --/--/---- by Orazio Czerwenka, 2:2450/540.55, GERMANY
  86.  
  87.  ***************************************************************************)
  88.  
  89. { ==========================================================================
  90.   WHICH VERSION OF TURBO PASCAL DO YOU COMPILE WITH ?
  91.   THE DEFAULT IS TURBO PASCAL 6.0x !
  92.   ========================================================================== }
  93.  
  94.   { The following conditional defines do not yet have any effect, ... }
  95.  
  96.   {.$define ver30}       { Turbo Pascal 3.0x }
  97.   {.$define ver40}       { Turbo Pascal 4.0x }
  98.   {.$define ver50}       { Turbo Pascal 5.0x }
  99.   {.$define ver55}       { Turbo Pascal 5.5x }
  100.   {$define ver60}       { Turbo Pascal 6.0x }
  101.   {.$define ver70}       { Turbo/Borland Pascal 7.0x }
  102.  
  103.   { ... these commenting lines will be deleted once that should be changed. }
  104.  
  105.  
  106. { ==========================================================================
  107.   WHAT LANGUAGE DO YOU WANT YOUR PROGRAMS TO DISPLAY MESSAGES IN BY DEFAULT?
  108.   ========================================================================== }
  109.  
  110.   {$define English}
  111.   {.$define German}
  112.  
  113.  
  114. { ==========================================================================
  115.   ACTIVATE THE FOLLOWING DISABLED COMPILER DIRECTIVE IF YOU WANT TO BE ABLE
  116.   TO USE THE UNIT SYSTEM FROM WITHIN OVERLAYS !
  117.   ========================================================================== }
  118.  
  119.   {.$O+}   { This tells your compiler - if activated - to produce a unit
  120.              that will be allowed to be used from within overlays. }
  121.  
  122.   {$IFOPT O+}
  123.     {$DEFINE Overlays}                                    { easier to read }
  124.   {$ENDIF}
  125.  
  126. { ==========================================================================
  127.   WHAT KIND OF PROCESSOR ARE YOU COMPILING FOR ? SOME CPU DEPENDEND DEFINES.
  128.   ========================================================================== }
  129.  
  130.   (* Some of the units use inline assembler designed to work on machines
  131.      with at least 80286 processor, so generally you can tell your compiler
  132.      to produce 80286 code anyway.
  133.   *)
  134.  
  135.   {$G+}   { This tells - if activated - your compiler to produce 80286
  136.             code. }
  137.  
  138.   (* In addition you might want to specify one of the following higher
  139.      processors, if you want your programmes ONLY to run on THESE and
  140.      higher machines.
  141.   *)
  142.  
  143.   { The following conditional defines do not yet have any effect, ... }
  144.  
  145.   {.$define cpu386}           { Use specific code for 80386 machines }
  146.   {.$define cpu486}           { Use specific code for 80486 machines }
  147.  
  148.   { ... these commenting lines will be deleted once that should be changed. }
  149.  
  150. { -------------------------------------------------------------------------- }
  151.  
  152.   (* Define one of the following CRT replacements (or CRT) for use by the
  153.      units FTMODE and FSPEAKER, depending on what you've got.
  154.      If you don't have a replacement, take the CRT, it is a bit slower but
  155.      it should work as well.
  156.      -----------------------------------------------------------------------
  157.      NOTICE THAT THE UNIT FCRT SHOULD ALSO BE INCLUDED IN THIS FILE PACKAGE!
  158.      -----------------------------------------------------------------------
  159.      Note that at least one of those units shoul be defined to be used !
  160.      By default this should be the unit FCRT.
  161.  
  162.      In case you should also want to use TP CRT's screen handling related
  163.      functions in addition to the routines provided by FCONDRV and FCRT
  164.      you probably will have to define the usage of TP's CRT here.
  165.      By default the usage of TP's CRT is *NOT* defined in order to avoid
  166.      smaller drawbacks in speed and unnecessarilly 'blown up' code.
  167.   *)
  168.  
  169.   {$define FCRT}
  170.   {.$define CRT}
  171.   {.$define CRT2}
  172.  
  173.  
  174.  
  175. { -------------------------------------------------------------------------- }
  176.  
  177.   (* The following conditional define will specify wether the unit(s) FTMODE
  178.      will use the BIOS for the 80x25 mode or try programming it by hand. You
  179.      should leave it inactivated, since who would want to force the user to
  180.      use 80x25 ? I (MM) implemented it, since on my system, mode 3 corresponds
  181.      to 90x28 through a TSR, and a small program would have helped here :-)
  182.      Note that forcing will only take place if FTMODE's SetVideoMode(3) does
  183.      not result in an 80 column mode.
  184.   *)
  185.  
  186. {.$define UseBIOS}
  187.  
  188.  
  189.  
  190. { -------------------------------------------------------------------------- }
  191.  
  192. ===== End   of includefile FDEFINE.DEF =====
  193.  
  194. ===== Start of unit FDPMI =====
  195.  
  196. Unit FDPMI; { routines for DOS/DPMI communication }
  197.  (***************************************************************************
  198.  
  199.            RELEASE 1.00 - as contained in the file PRUS100.LZH
  200.                  by Max Maischein, 2:244/1106.17, GERMANY
  201.  
  202.                --------------------------------------------
  203.                 organized for Fido's PASCAL related echoes
  204.                --------------------------------------------
  205.  
  206.      06/15/1994 to --/--/---- by Max Maischein, 2:244/1106.17, GERMANY
  207.  
  208.            As far as third party copyrights are not violated this
  209.            source code is hereby placed to the public domain. Use
  210.            it whatever way you want, but use AT YOUR OWN RISK.
  211.  
  212.            In case you should modify the source rather send your
  213.            modifications to the unit's current organizer (see above for
  214.            NM address) than to spread it on your own. This will help to
  215.            keep the unit updated and grant a certain standard to all
  216.            other users as well.
  217.  
  218.            The unit is currently still under work. So it might greatly
  219.            benefit of your participation.
  220.  
  221.            Those who contributed to the following piece of source,
  222.            listed in alphabethical order:
  223.         ================================================================
  224.            Jochen Magnus (SEGDEMO.PAS), Max Maischein (collecting,
  225.            documenting, testing etc.), Raphael Vanney (program CHARSET
  226.            .PAS)
  227.         ================================================================
  228.            YOUR NAME WILL APPEAR HERE IF YOU CONTRIBUTE USEFUL SOURCE.
  229.  
  230.  ***************************************************************************)
  231.  
  232. {$I FDEFINE.DEF}
  233.  
  234. Interface
  235.  
  236. Type TRealModeRegs  =
  237.      Record
  238.           Case Integer Of
  239.           0: ( EDI, ESI, EBP, EXX, EBX, EDX, ECX, EAX: Longint;
  240.                Flags, ES, DS, FS, GS, IP, CS, SP, SS: Word) ;
  241.           1: ( DI,DIH, SI, SIH, BP, BPH, XX, XXH: Word;
  242.                Case Integer of
  243.                  0: (BX, BXH, DX, DXH, CX, CXH, AX, AXH: Word);
  244.                  1: (BL, BH, BLH, BHH, DL, DH, DLH, DHH,
  245.                      CL, CH, CLH, CHH, AL, AH, ALH, AHH: Byte));
  246.      End;
  247. (* Use these and RealModeInt() instead of Registers and Intr() under DPMI *)
  248.  
  249. Type TLongRec = Record
  250.        Case Byte of
  251.          0 : ( L : LongInt );
  252.          1 : ( wLo : Word;
  253.                wHi : Word; );
  254.          2 : ( iLo : Integer;
  255.                iHi : Integer );
  256.      End;
  257.  
  258. Function RealModeInt( IntNo : Byte; Var RealRegs : TRealModeRegs) : Boolean;
  259. (* Replacement for Intr(), returns False on error *)
  260.  
  261. Function NewSelector( Base, Limit : Longint) : Word;
  262. (* Returns a new selector for the range [Base - (Base+Limit)]        *)
  263. (* Base is the linear address of the memory location you want to use *)
  264. (* You must free this selector after use with FreeSelector()         *)
  265.  
  266. Function AllocateLowMem( Size : Word; var PMPointer : Pointer ) : Word;
  267. (* Allocates some memory in the first MB *)
  268. (* Returns a pointer to it and a segment to pass to the real mode routine *)
  269.  
  270. Procedure FreeLowMem(Var PMPointer : Pointer );
  271. (* Frees memory allocated with AllocateLowMem() *)
  272.  
  273. Implementation
  274. Uses WinAPI;
  275.  
  276. Function RealModeInt( IntNo : Byte; Var RealRegs : TRealModeRegs) : Boolean;
  277. Assembler;
  278. { This function switches to real mode and issues the specified interrupt,
  279.   after filling the registers with values stored in RealRegs.
  280.   If SS/SP as specified in RealRegs are Nil, the DPMI server provides a
  281.   small stack. For more discution of this, see Ralf Brown's INTERxx.ZIP }
  282. Asm
  283.                         mov     ax, 0300h       { DPMI function "simulate real
  284. mode int" }
  285.                         mov     bl, [IntNo]
  286.                         xor     bh, bh          { 0 as requested by DPMI v1.0
  287. }                        xor     cx, cx          { bytes to copy onto "remote"
  288. stack }
  289.                         les     di, [RealRegs]
  290.                         int     31h             { Returns CF set on error }
  291.                         mov     ax, 1           { assume everything went OK }
  292.                         sbb     ax, 0           { if carry set, decrement ax }
  293.                                                 { to signal an error }
  294. End;
  295.  
  296. Function NewSelector(Base,Limit:longint) : Word;
  297. Var Sel : Word;
  298. Begin
  299.   Sel := AllocSelector(0);
  300.   If (sel<>0) and (setSelectorBase(sel,base)=sel) and (setSelectorLimit(sel,
  301. limit)=0)
  302.     then newSelector:=sel
  303.     else newSelector:=0;
  304. End;
  305.  
  306. Function AllocateLowMem( Size : Word; var PMPointer : Pointer ) : Word;
  307. { This procedure allocates memory in the first megabyte, and returns two
  308.   ways of accessing it : a pointer valid in protected mode, and the
  309.   segment part of a pointer valid in real mode ; offset part is always 0 }
  310.  
  311. Var  Adr  : LongInt ;
  312. Begin
  313.   Adr:=GlobalDOSAlloc(Size) ;
  314.   If Adr=0 then RunError( 0 );
  315.   PMPointer := Ptr( TLongRec(Adr).wLo, 0);
  316.   AllocateLowMem := TLongRec(Adr).wHi;
  317. End ;
  318.  
  319. Procedure FreeLowMem(Var PMPointer : Pointer ) ;
  320. { Frees memory allocated with AllocateLowMem }
  321. Begin
  322.   GlobalDOSFree(Seg( PMPointer^ ));
  323.   PMPointer := nil;
  324. End ;
  325. {$IFnDEF DPMI}
  326. {$IFnDEF Windows}
  327.   You are compiling WHAT ??
  328. {$ENDIF}
  329. {$ENDIF}
  330. End.
  331.  
  332. ===== End   of unit FDPMI =====
  333.